package org.dtrd.modules.doctor.job;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.util.JSONUtils;
import org.dtrd.common.util.StringUtil;
import org.dtrd.config.system.Constant;
import org.dtrd.modules.achievement.service.IDtrdEntRdSigninPlanService;
import org.dtrd.modules.achievement.service.IDtrdEntRdSigninRecordService;
import org.dtrd.modules.archive.entity.po.DtrdEntRdArchiveOverview;
import org.dtrd.modules.archive.service.IDtrdEntRdOverviewService;
import org.dtrd.modules.doctor.entity.po.DtrdEntRdDoctorStatisticInfo;
import org.dtrd.modules.doctor.entity.po.DtrdRlDoctorPatient;
import org.dtrd.modules.doctor.entity.po.DtrdRlStatisticsDoctorPatient;
import org.dtrd.modules.doctor.service.*;
import org.dtrd.modules.patient.entity.po.DtrdEntRdPatient;
import org.dtrd.modules.patient.service.IDtrdEntRdPatientService;
import org.dtrd.modules.record.entity.po.DtrdEntRdSigninSugarValue;
import org.dtrd.modules.record.service.ISugarRecordService;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 生成医生首页统计数据的定时任务
 *
 * @author qr
 * @date 2022/4/14 12:55
 */
@Component
@Slf4j
public class DoctorStatisticInfoJob implements Job {

    @Autowired
    private IDtrdEntRdDoctorService doctorService;
    @Autowired
    private IDtrdRlDoctorTeamDoctorService doctorTeamDoctorService;
    @Autowired
    private IDtrdEntRdDoctorTeamService doctorTeamService;
    @Autowired
    private IDtrdRlDoctorPatientService doctorPatientRlService;
    @Autowired
    private IDtrdEntRdPatientService patientService;
    @Autowired
    private IDtrdEntRdOverviewService overviewService;
    @Autowired
    private IDtrdEntRdDoctorStatisticInfoService doctorStatisticInfoService;
    @Autowired
    private ISugarRecordService sugarRecordService;
    @Autowired
    private IDtrdEntRdSigninRecordService signinRecordService;
    @Autowired
    private IDtrdEntRdSigninPlanService signinPlanService;

    @Autowired
    private IDtrdRlStatisticsDoctorPatientService statisticsDoctorPatientService;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//        handleDailyH5Statistics();
        // 仅获取医生身份的统计数据
//        List<Integer> doctorIds = doctorService.listDoctorIdsByDoctorType(Constant.Executor.DOCTOR.getType(), Executor.MANAGE_DOCTOR.getType());
        List<Integer> doctorIds = doctorService.listDoctorIdsByDoctorType(null);
        // 处理医生的统计数据
        if (CollectionUtil.isNotEmpty(doctorIds)) {
            List<DtrdEntRdDoctorStatisticInfo> statisticInfoList = new ArrayList<>(doctorIds.size());
            Map<String, List<DtrdEntRdDoctorStatisticInfo>> orgMap = new HashMap<>(doctorIds.size() / 2);
            Map<Integer, List<DtrdEntRdDoctorStatisticInfo>> teamMap = new HashMap<>(doctorIds.size() / 2);

            for (Integer doctorId : doctorIds) {
                //// 按医生个人统计
                DtrdEntRdDoctorStatisticInfo statisticInfo = statisticDoctorInfo(doctorId);
                if (statisticInfo != null) {
                    // 按照团队计算
                    if (statisticInfo.getTeamId() != null) {
                        List<DtrdEntRdDoctorStatisticInfo> tmpList = teamMap.getOrDefault(statisticInfo.getTeamId(), new ArrayList<>(10));
                        tmpList.add(statisticInfo);
                        teamMap.put(statisticInfo.getTeamId(), tmpList);
                    }
                    // 按机构计算
                    if (statisticInfo.getOrgCode() != null) {
                        List<DtrdEntRdDoctorStatisticInfo> tmpList = orgMap.getOrDefault(statisticInfo.getOrgCode(), new ArrayList<>(10));
                        tmpList.add(statisticInfo);
                        orgMap.put(statisticInfo.getOrgCode(), tmpList);
                    }
                }
            }
            List<DtrdEntRdDoctorStatisticInfo> dataList = new ArrayList<>(teamMap.size());
            Map<Integer, DtrdEntRdDoctorStatisticInfo> teamResultMap = handleStatisticsMap(teamMap, teamId -> {
                DtrdEntRdDoctorStatisticInfo statisticInfo = new DtrdEntRdDoctorStatisticInfo().init();
                statisticInfo.setTeamId(teamId);
                return statisticInfo;
            });
            Collection<DtrdEntRdDoctorStatisticInfo> values = teamResultMap.values();
            if (CollectionUtils.isNotEmpty(values)) {
                dataList.addAll(values);
            }

            Map<String, DtrdEntRdDoctorStatisticInfo> orgResultMap = handleStatisticsMap(orgMap, orgCode -> {
                DtrdEntRdDoctorStatisticInfo statisticInfo = new DtrdEntRdDoctorStatisticInfo().init();
                statisticInfo.setOrgCode(orgCode);
                return statisticInfo;
            });
            Collection<DtrdEntRdDoctorStatisticInfo> values2 = orgResultMap.values();
            if (CollectionUtils.isNotEmpty(values2)) {
                dataList.addAll(values2);
            }
            if (CollectionUtil.isNotEmpty(dataList)) {
                doctorStatisticInfoService.saveBatch(dataList);
            }
        }

    }
    //region ======================================== 团队统计 ========================================

    private <T> Map<T, DtrdEntRdDoctorStatisticInfo> handleStatisticsMap(Map<T, List<DtrdEntRdDoctorStatisticInfo>> map, Function<T, DtrdEntRdDoctorStatisticInfo> mapper) {
        if (CollectionUtil.isNotEmpty(map)) {
            Map<T, DtrdEntRdDoctorStatisticInfo> dataMap = new HashMap<>(map.keySet().size());
            map.keySet().forEach(key -> {
                DtrdEntRdDoctorStatisticInfo statisticInfo = mapper.apply(key);
                List<DtrdEntRdDoctorStatisticInfo> list = map.get(key);
                Map<Integer, Integer> mapSugar = new HashMap<>(10), mapDiet = new HashMap<>(10),
                        mapSport = new HashMap<>(10), mapMedical = new HashMap<>(10),
                        mapInsulin = new HashMap<>(10), mapPressure = new HashMap<>(10),
                        mapKetone = new HashMap<>(10), mapWaist = new HashMap<>(10),
                        mapWeight = new HashMap<>(10), mapSleep = new HashMap<>(10),
                        mapNutrient = new HashMap<>(10);
                list.forEach(item -> {
                    // 患者数目统计
                    statisticInfo.setPatientCount(sumValue(statisticInfo.getPatientCount(), item.getPatientCount()));
                    // 糖前期
                    statisticInfo.setPatientPrediabetes(sumValue(statisticInfo.getPatientPrediabetes(), item.getPatientPrediabetes()));
                    // 血糖数统计
                    statisticInfo.setPatientSugarCount(sumValue(statisticInfo.getPatientSugarCount(), item.getPatientSugarCount()));
                    // 性别统计
                    statisticInfo.setPatientSexMale(sumValue(statisticInfo.getPatientSexMale(), item.getPatientSexMale()));
                    statisticInfo.setPatientSexFemale(sumValue(statisticInfo.getPatientSexFemale(), item.getPatientSexFemale()));
                    // 糖尿病类型
                    statisticInfo.setPatientDiabetesType1(sumValue(statisticInfo.getPatientDiabetesType1(), item.getPatientDiabetesType1()));
                    statisticInfo.setPatientDiabetesType2(sumValue(statisticInfo.getPatientDiabetesType2(), item.getPatientDiabetesType2()));
                    statisticInfo.setPatientDiabetesTypeGestation(sumValue(statisticInfo.getPatientDiabetesTypeGestation(), item.getPatientDiabetesTypeGestation()));
                    statisticInfo.setPatientDiabetesTypeOther(sumValue(statisticInfo.getPatientDiabetesTypeOther(), item.getPatientDiabetesTypeOther()));
                    // 年龄统计
                    statisticInfo.setPatientAge1(sumValue(statisticInfo.getPatientAge1(), item.getPatientAge1()));
                    statisticInfo.setPatientAge2(sumValue(statisticInfo.getPatientAge2(), item.getPatientAge2()));
                    statisticInfo.setPatientAge3(sumValue(statisticInfo.getPatientAge3(), item.getPatientAge3()));
                    statisticInfo.setPatientAge4(sumValue(statisticInfo.getPatientAge4(), item.getPatientAge4()));
                    statisticInfo.setPatientAge5(sumValue(statisticInfo.getPatientAge5(), item.getPatientAge5()));
                    // 糖龄统计
                    statisticInfo.setPatientSugarAge1(sumValue(statisticInfo.getPatientSugarAge1(), item.getPatientSugarAge1()));
                    statisticInfo.setPatientSugarAge2(sumValue(statisticInfo.getPatientSugarAge2(), item.getPatientSugarAge2()));
                    statisticInfo.setPatientSugarAge3(sumValue(statisticInfo.getPatientSugarAge3(), item.getPatientSugarAge3()));
                    statisticInfo.setPatientSugarAge4(sumValue(statisticInfo.getPatientSugarAge4(), item.getPatientSugarAge4()));
                    // 日常检测数据
                    sumMapValue(mapSugar, item.getPatientSigninSugar());
                    sumMapValue(mapDiet, item.getPatientSigninDiet());
                    sumMapValue(mapSport, item.getPatientSigninSport());
                    sumMapValue(mapMedical, item.getPatientSigninMedical());
                    sumMapValue(mapInsulin, item.getPatientSigninInsulin());
                    sumMapValue(mapPressure, item.getPatientSigninPressure());
                    sumMapValue(mapKetone, item.getPatientSigninKetone());
                    sumMapValue(mapWaist, item.getPatientSigninWaist());
                    sumMapValue(mapWeight, item.getPatientSigninWeight());
                    sumMapValue(mapSleep, item.getPatientSigninSleep());
                    sumMapValue(mapNutrient, item.getPatientSigninNutrient());
                });
                statisticInfo.setPatientSigninSugar(JSONUtil.toJsonStr(mapSugar));
                statisticInfo.setPatientSigninDiet(JSONUtil.toJsonStr(mapDiet));
                statisticInfo.setPatientSigninSport(JSONUtil.toJsonStr(mapSport));
                statisticInfo.setPatientSigninMedical(JSONUtil.toJsonStr(mapMedical));
                statisticInfo.setPatientSigninInsulin(JSONUtil.toJsonStr(mapInsulin));
                statisticInfo.setPatientSigninPressure(JSONUtil.toJsonStr(mapPressure));
                statisticInfo.setPatientSigninKetone(JSONUtil.toJsonStr(mapKetone));
                statisticInfo.setPatientSigninWaist(JSONUtil.toJsonStr(mapWaist));
                statisticInfo.setPatientSigninWeight(JSONUtil.toJsonStr(mapWeight));
                statisticInfo.setPatientSigninSleep(JSONUtil.toJsonStr(mapSleep));
                statisticInfo.setPatientSigninNutrient(JSONUtil.toJsonStr(mapNutrient));
                log.info("DoctorStatisticInfoJob.handleStatisticsMap.[map, mapper] statisticInfo" + statisticInfo);
                dataMap.put(key, statisticInfo);
            });
            return dataMap;
        }
        return null;
    }

    private Integer sumValue(Integer patientAge1, Integer age1) {
        if (age1 != null) {
            if (patientAge1 == null) {
                patientAge1 = 0;
            }
            patientAge1 += age1;
        }
        return patientAge1;
    }

    private Map<Integer, Integer> sumMapValue(Map<Integer, Integer> map, String mapJson) {
        if (StrUtil.isNotBlank(mapJson)) {
            JSONObject jsonObject = JSON.parseObject(mapJson);
            jsonObject.keySet().forEach(key->{
                Integer keyValue=StringUtil.StrTrimInt(key);
                log.info("DoctorStatisticInfoJob.sumMapValue.[map, mapJson] key=" + key + "; keyValue=" + keyValue + ";jsonObject.getInteger(key)=" + jsonObject.getInteger(key));
                map.put(keyValue, sumValue(map.getOrDefault(keyValue, 0), jsonObject.getInteger(key)));
            });
        }
        return map;
    }

    //endregion ======================================== 团队统计 ========================================


    //region ======================================== OMS 医生首页统计 ========================================

    /**
     * 统计医生相关患者数据
     *
     * @return
     */
    private DtrdEntRdDoctorStatisticInfo statisticDoctorInfo(Integer doctorId) {
        List<Integer> patientIds = doctorPatientRlService.listPatientIdsByDoctorId(doctorId);
        if (CollectionUtil.isNotEmpty(patientIds)) {
            String orgCode = doctorService.getDoctorOrgCodeById(doctorId);
            Integer teamId = doctorTeamDoctorService.geTeamIdByDoctorId(doctorId);
            DtrdEntRdDoctorStatisticInfo statisticInfo = new DtrdEntRdDoctorStatisticInfo();
            statisticInfo.setDoctorId(doctorId);
            statisticInfo.setPatientCount(patientIds.size());
            //region 糖尿病概况表信息，可查糖尿病类型，糖龄，以及用药类型
            List<DtrdEntRdArchiveOverview> overviews = overviewService.listOverviewByPatientIds(patientIds);
            if (CollectionUtil.isNotEmpty(overviews)) {
                handleOverview(overviews, statisticInfo);
            }
            //endregion
            //region patient 表信息，性别，年龄
            List<DtrdEntRdPatient> patients = patientService.listPatientsByIds(patientIds);
            if (CollectionUtil.isNotEmpty(patients)) {
                handlePatient(patients, statisticInfo);
            }
            //endregion
            //region 血糖总数
            List<DtrdEntRdSigninSugarValue> values = sugarRecordService.listSugarValuesByPatientIds(patientIds);
            statisticInfo.setPatientSugarCount(values.size());
            //endregion
            //region 处理打卡状态
            List<Map<Integer, Integer>> signinStatus = new ArrayList<>(patientIds.size());
            for (Integer patientId : patientIds) {
                Map<Integer, Map<Integer, Integer>> signinPlanMap = signinPlanService.getPatientSigninCountByType(patientId);
                Map<Integer, Map<Integer, Integer>> signinRecordMap = signinRecordService.getSigninRecordByPatientId(patientId);
                Map<Integer, Integer> weekDayMap = signinRecordService.getPatientSigninRecordWeekDayMap(patientId);
                if (MapUtil.isNotEmpty(signinPlanMap) && MapUtil.isNotEmpty(signinRecordMap) && MapUtil.isNotEmpty(weekDayMap)) {
                    Map<Integer, Integer> patientSigninStatus = handleSigninAndRecordMap(signinRecordMap, signinPlanMap, weekDayMap);
                    signinStatus.add(patientSigninStatus);
                }
            }
            if (CollectionUtil.isNotEmpty(signinStatus)) {
                countSigninStatus(signinStatus, statisticInfo);
                toBarData(signinStatus, statisticInfo);
            }
            statisticInfo.setTeamId(teamId);
            statisticInfo.setOrgCode(orgCode);
            //endregion
            doctorStatisticInfoService.save(statisticInfo);
            return statisticInfo;
        } else {
            List<DtrdEntRdDoctorStatisticInfo> list = doctorStatisticInfoService.getDoctorStatisticInfoList(doctorId, null,1);
            if (CollectionUtil.isNotEmpty(list)) {
                doctorStatisticInfoService.removeByDoctorId(doctorId);
            }
        }
        return null;
    }

    // 处理患者的打卡率
    private void toBarData(List<Map<Integer, Integer>> signinStatus, DtrdEntRdDoctorStatisticInfo statisticInfo) {
        HashMap<Integer, Integer> result = new HashMap<>(11);
        List<Integer> types = Arrays.stream(Constant.RecordType.values())
                .map(Constant.RecordType::getType)
                .collect(Collectors.toList());
        // 计算各项打卡的打卡率平均值
        for (Integer type : types) {
            int count = 0;
            int rateCount = 0;
            for (Map<Integer, Integer> status : signinStatus) {
                Integer rate = status.get(type);
                if (rate != null) {
                    rateCount += rate;
                    count++;
                }
            }
            if (count != 0) {
                result.put(type, rateCount / count);
            }
        }
        statisticInfo.setPatientSigninBarChart(JSONUtil.toJsonStr(result));
    }

    /**
     * 处理每个患者的每项打卡状况
     */
    private void countSigninStatus(List<Map<Integer, Integer>> signinStatusList, DtrdEntRdDoctorStatisticInfo statisticInfo) {
        if (CollectionUtil.isNotEmpty(signinStatusList)) {
            // 血糖/血压/运动/用药/饮食/体重/腰围/尿酮/胰岛素/睡眠
            Map<Integer, Integer> map1 = new HashMap<>(10), map2 = new HashMap<>(10),
                    map3 = new HashMap<>(10), map4 = new HashMap<>(10), map5 = new HashMap<>(10),
                    map6 = new HashMap<>(10), map7 = new HashMap<>(10), map8 = new HashMap<>(10),
                    map9 = new HashMap<>(10), map10 = new HashMap<>(10),map11 = new HashMap<>(10);
            for (Map<Integer, Integer> status : signinStatusList) {
                for (Map.Entry<Integer, Integer> entry : status.entrySet()) {
                    Integer signinType = entry.getKey();
                    Integer rate = entry.getValue();
                    Constant.RecordType type = Constant.RecordType.valueOf(signinType);
                    assert type != null;
                    switch (type) {
                        case SUGAR:
                            countSignTypeRateStatus(map1, rate);
                            break;
                        case BLOOD_PRESSURE:
                            countSignTypeRateStatus(map2, rate);
                            break;
                        case SPORT:
                            countSignTypeRateStatus(map3, rate);
                            break;
                        case MEDICAL:
                            countSignTypeRateStatus(map4, rate);
                            break;
                        case DIET:
                            countSignTypeRateStatus(map5, rate);
                            break;
                        case WEIGHT:
                            countSignTypeRateStatus(map6, rate);
                            break;
                        case WAIST:
                            countSignTypeRateStatus(map7, rate);
                            break;
                        case KETONE:
                            countSignTypeRateStatus(map8, rate);
                            break;
                        case INSULIN:
                            countSignTypeRateStatus(map9, rate);
                            break;
                        case SLEEP:
                            countSignTypeRateStatus(map10, rate);
                            break;
                        case NUTRIENT:
                            countSignTypeRateStatus(map11, rate);
                            break;
                    }
                }
            }
            if (MapUtil.isNotEmpty(map1)) {
                statisticInfo.setPatientSigninSugar(JSONUtil.toJsonStr(map1));
            }
            if (MapUtil.isNotEmpty(map2)) {
                statisticInfo.setPatientSigninPressure(JSONUtil.toJsonStr(map2));
            }
            if (MapUtil.isNotEmpty(map3)) {
                statisticInfo.setPatientSigninSport(JSONUtil.toJsonStr(map3));
            }
            if (MapUtil.isNotEmpty(map4)) {
                statisticInfo.setPatientSigninMedical(JSONUtil.toJsonStr(map4));
            }
            if (MapUtil.isNotEmpty(map5)) {
                statisticInfo.setPatientSigninDiet(JSONUtil.toJsonStr(map5));
            }
            if (MapUtil.isNotEmpty(map6)) {
                statisticInfo.setPatientSigninWeight(JSONUtil.toJsonStr(map6));
            }
            if (MapUtil.isNotEmpty(map7)) {
                statisticInfo.setPatientSigninWaist(JSONUtil.toJsonStr(map7));
            }
            if (MapUtil.isNotEmpty(map8)) {
                statisticInfo.setPatientSigninKetone(JSONUtil.toJsonStr(map8));
            }
            if (MapUtil.isNotEmpty(map9)) {
                statisticInfo.setPatientSigninInsulin(JSONUtil.toJsonStr(map9));
            }
            if (MapUtil.isNotEmpty(map10)) {
                statisticInfo.setPatientSigninSleep(JSONUtil.toJsonStr(map10));
            }
            if (MapUtil.isNotEmpty(map11)) {
                statisticInfo.setPatientSigninNutrient(JSONUtil.toJsonStr(map11));
            }
        }
    }

    private void countSignTypeRateStatus(Map<Integer, Integer> map, Integer rate) {
        if (rate <= 10) {
            Integer count = map.getOrDefault(Constant.SigninPlanPercentage.PERCENTAGE_1.getType(), 0);
            map.put(1, ++count);
        } else if (rate <= 20) {
            Integer count = map.getOrDefault(Constant.SigninPlanPercentage.PERCENTAGE_2.getType(), 0);
            map.put(2, ++count);
        } else if (rate <= 30) {
            Integer count = map.getOrDefault(Constant.SigninPlanPercentage.PERCENTAGE_3.getType(), 0);
            map.put(3, ++count);
        } else if (rate <= 40) {
            Integer count = map.getOrDefault(Constant.SigninPlanPercentage.PERCENTAGE_4.getType(), 0);
            map.put(4, ++count);
        } else if (rate <= 50) {
            Integer count = map.getOrDefault(Constant.SigninPlanPercentage.PERCENTAGE_5.getType(), 0);
            map.put(5, ++count);
        } else if (rate <= 60) {
            Integer count = map.getOrDefault(Constant.SigninPlanPercentage.PERCENTAGE_6.getType(), 0);
            map.put(6, ++count);
        } else if (rate <= 70) {
            Integer count = map.getOrDefault(Constant.SigninPlanPercentage.PERCENTAGE_7.getType(), 0);
            map.put(7, ++count);
        } else if (rate <= 80) {
            Integer count = map.getOrDefault(Constant.SigninPlanPercentage.PERCENTAGE_8.getType(), 0);
            map.put(8, ++count);
        } else if (rate <= 90) {
            Integer count = map.getOrDefault(Constant.SigninPlanPercentage.PERCENTAGE_9.getType(), 0);
            map.put(9, ++count);
        } else {
            Integer count = map.getOrDefault(Constant.SigninPlanPercentage.PERCENTAGE_10.getType(), 0);
            map.put(10, ++count);
        }
    }

    /**
     * 传捡来的时 星期数：打卡类型：打卡次数
     * 计算打卡率 打卡总数 / 打卡次数
     * 处理打卡记录和打卡计划的map，需要返回一个各个打卡项的百分比map 打卡项: 百分比数
     */
    private Map<Integer, Integer> handleSigninAndRecordMap(Map<Integer, Map<Integer, Integer>> signinRecordMap,
                                                           Map<Integer, Map<Integer, Integer>> signinPlanMap,
                                                           Map<Integer, Integer> weekDayMap) {
        Map<Integer, Integer> map = new HashMap<>();
        Set<Integer> weekDays = signinPlanMap.keySet();
        for (Integer weekDay : weekDays) {
            Map<Integer, Integer> planMap = signinPlanMap.get(weekDay);
            Map<Integer, Integer> recordMap = signinRecordMap.get(weekDay);
            // 这里如果 recordMap == null 说明没有这个星期数的打卡记录
            if (recordMap != null) {
                for (Map.Entry<Integer, Integer> entry : planMap.entrySet()) {
                    Integer signinType = entry.getKey();
                    int planCount = entry.getValue() * weekDayMap.get(weekDay);
                    Integer recordCount = recordMap.getOrDefault(signinType, 0);
                    int rate = Math.min(recordCount * 100 / planCount, 100);
                    Integer typeRate = map.getOrDefault(signinType, 0);
                    map.put(signinType, typeRate + rate);
                }
            }
        }
        // 处理下求平均值
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            Integer totalRate = entry.getValue();
            entry.setValue(Math.min(totalRate / signinPlanMap.keySet().size(), 100));
        }
        return map;
    }

    /**
     * 处理患者表
     */
    private void handlePatient(List<DtrdEntRdPatient> patients, DtrdEntRdDoctorStatisticInfo statisticInfo) {
        // c1：男，c2：女，c3：0～10岁，c4：11～20岁，c5：20～40岁，c6：40～60岁，c7：60岁以上
        int c1 = 0, c2 = 0, c3 = 0, c4 = 0, c5 = 0, c6 = 0, c7 = 0;
        for (DtrdEntRdPatient patient : patients) {
            //region 性别
            Integer sex = patient.getPatientsSex();
            if (sex != null) {
                Constant.Sex type = Constant.Sex.valueOf(sex);
                switch (type) {
                    case MAN:
                        c1++;
                        break;
                    case WOMAN:
                        c2++;
                        break;
                }
            }
            //endregion
            //region 年龄
            Date birthday = patient.getPatientsBirthday();
            if (birthday != null) {
                long between = DateUtil.between(birthday, new Date(), DateUnit.DAY);
                if (between <= 10 * 365) {
                    c3++;
                } else if (between <= 20 * 365) {
                    c4++;
                } else if (between <= 40 * 365) {
                    c5++;
                } else if (between <= 60 * 365) {
                    c6++;
                } else {
                    c7++;
                }
            }
            //endregion
        }
        // 处理值
        statisticInfo.setPatientSexMale(c1);
        statisticInfo.setPatientSexFemale(c2);
        statisticInfo.setPatientAge1(c3);
        statisticInfo.setPatientAge2(c4);
        statisticInfo.setPatientAge3(c5);
        statisticInfo.setPatientAge4(c6);
        statisticInfo.setPatientAge5(c7);
    }

    /**
     * 处理糖尿病概况信息
     */
    private void handleOverview(List<DtrdEntRdArchiveOverview> overviews, DtrdEntRdDoctorStatisticInfo statisticInfo) {
        // 1：1型糖尿病数，2：2型糖尿病数，3：妊娠型糖尿病数，4：其他类型糖尿病数，5：糖尿病前期
        // 6：糖龄小于1年，7：糖龄1～5年，8：糖龄5～10年，9：糖龄10年以上
        int c1 = 0, c2 = 0, c3 = 0, c4 = 0, c5 = 0, c6 = 0, c7 = 0, c8 = 0, c9 = 0, dp1 = 0, dp2 = 0, dp3 = 0;
        for (DtrdEntRdArchiveOverview overview : overviews) {
            //region 计算糖尿病类型
            Integer diabetesType = overview.getDiabetesType();
            if (diabetesType != null) {
                Constant.DiabetesType type = Constant.DiabetesType.valueOf(diabetesType);
                switch (type) {
                    case DIABETES_TYPE_1:
                        c1++;
                        break;
                    case DIABETES_TYPE_2:
                        c2++;
                        break;
                    case DIABETES_TYPE_PREGNANCY:
                        c3++;
                        break;
                    case DIABETES_TYPE_OTHER:
                        c4++;
                        break;
                }
            }
            //endregion
            //region 糖尿病前期
            Date diagnoseDate = overview.getDiabetesDiagnoseDate();
            if (diagnoseDate != null) {
                long between = DateUtil.between(diagnoseDate, new Date(), DateUnit.DAY);
                if (between <= 365) {
                    c5++;
                    c6++;
                } else if (between <= 365 * 5) {
                    c5++;
                    c7++;
                } else if (between <= 365 * 10) {
                    c8++;
                } else {
                    c9++;
                }
            }
            //endregion
            //region 用药类型
            Integer drugType = overview.getDrugType();
            Constant.DrugType type = Constant.DrugType.valueOf(drugType);
            switch (type) {
                case NO:
                    dp1++;
                    break;
                case ORAL_DRUG:
                    dp2++;
                    break;
                case INSULIN:
                    dp3++;
                    break;
            }
            //endregion
        }
        // 处理值
        statisticInfo.setPatientDiabetesType1(c1);
        statisticInfo.setPatientDiabetesType2(c2);
        statisticInfo.setPatientDiabetesTypeGestation(c3);
        statisticInfo.setPatientDiabetesTypeOther(c4);
        statisticInfo.setPatientPrediabetes(c5);
        statisticInfo.setPatientSugarAge1(c6);
        statisticInfo.setPatientSugarAge2(c7);
        statisticInfo.setPatientSugarAge3(c8);
        statisticInfo.setPatientSugarAge4(c9);
        // 用药类型
        statisticInfo.setPatientDrugType1(dp1);
        statisticInfo.setPatientDrugType2(dp2);
        statisticInfo.setPatientDrugType3(dp3);
    }

    //endregion ======================================== OMS 医生首页统计 ========================================

    //region ======================================== 统计医生今日测量记录数、未测量患者数、重点关注患者 ========================================

    /**
     * 生成医生关联患者统计当日测量数、未测量、重点关注、扫码患者关联记录
     */
    private void handleDailyH5Statistics() {
        List<DtrdRlDoctorPatient> list = doctorPatientRlService.getRelativeRecords();
        if (CollectionUtil.isNotEmpty(list)) {
            List<DtrdRlStatisticsDoctorPatient> rlStatisticsList = new ArrayList<>(list.size() / 3);
            Map<Integer, DtrdRlStatisticsDoctorPatient> map = new HashMap<>(list.size() / 3);
            list.forEach(item -> {
                DtrdRlStatisticsDoctorPatient rlStatisticsDoctorPatient = map.get(item.getDoctorId());
                if (rlStatisticsDoctorPatient == null) {
                    rlStatisticsDoctorPatient = new DtrdRlStatisticsDoctorPatient().init();
                    rlStatisticsDoctorPatient.setDoctorId(item.getDoctorId());
                    rlStatisticsDoctorPatient.setMeasureNum(0);
                    rlStatisticsDoctorPatient.setScanCount(0);
                    rlStatisticsDoctorPatient.setConcernNum(0);
                    rlStatisticsDoctorPatient.setUnMeasurePatientNum(0);
                }
                int concernSum = rlStatisticsDoctorPatient.getConcernNum();
                if (StringUtil.StrTrimInt(item.getDoctorPatientConcern()) != 0) {
                    concernSum += 1;
                    rlStatisticsDoctorPatient.setConcernNum(concernSum);
                }
                int unMeasurePatientNum = rlStatisticsDoctorPatient.getUnMeasurePatientNum();
                unMeasurePatientNum += 1;
                rlStatisticsDoctorPatient.setUnMeasurePatientNum(unMeasurePatientNum);
                map.put(item.getDoctorId(), rlStatisticsDoctorPatient);
            });
            log.info("DoctorStatisticInfoJob.handleDailyH5Statistics.[] map=" + map);
            map.keySet().forEach(key -> {
                DtrdRlStatisticsDoctorPatient po = map.get(key);
                po.setRecordDate(new Date());
                rlStatisticsList.add(po);
            });
            statisticsDoctorPatientService.saveBatch(rlStatisticsList);
        }
    }

    //endregion ======================================== 统计医生今日测量记录数、未测量患者数、重点关注患者 ========================================

}
